###########################################################################
# $Id: labourTidyConfig.p 49 2009-07-15 06:56:22Z donbeave $
###########################################################################

@CLASS
labourTidyConfig

@USE
pf/tests/pfAssert.p
pf/types/pfString.p

@OPTIONS
locals

#----- Static constructor -----

@auto[]
  $self._defaultOptions[
    $.tabSize(4)
    $.wrap(0)
    $.hideEndtags(true)
    $.quiet(true)
    $.bare(true)
    $.doctype[omit]
    $.dropFontTags(true)
    $.indent[auto]
    $.forceOutput(true)
    $.charEncoding[utf8]
    $.dropEmptyParas(false)
    $.word2000(true)
    $.tidyMark(false)
  ]

  $self._isConfigLoaded(false)

  $self._abbrRegex[(html|xhtml|xml|uri|cdata|php|jste|ascii)]

  $self._loadedConfig[^hash::create[]]

#----- Constructor -----

@create[objTidy]
  ^pfAssert:isTrue(def $objTidy && $objTidy is labourTidy)[Tidy object is not specified.]

  $self._tidy[$objTidy]

  $self._config[^hash::create[$self._defaultOptions]]

#----- Public -----

@save[strFileName]
  $result[]

  ^if(-f $strFileName){
    ^file:delete[$strFileName]
  }

  ^self._config.foreach[sName;aData]{
    ^if(def $aData){
      $sData[^_restoreName[$sName]: ^if($aData is bool){^if($aData){yes}{no}}{$aData}^#0A]

      ^sData.save[append;$strFileName]
    }
  }

#----- Properties -----

@GET_DEFAULT[strName]
  ^if(^self._config.contains[$strName] || ^self._loadedConfig.contains[$strName]){
    $result[^if(def $self._config.[$strName]){$self._config.[$strName]}{$self._loadedConfig.[$strName]}]
  }{
     ^if(!$self._isConfigLoaded){
       ^_loadConfig[]

       $result[$self.[$strName]]
     }{
        ^pfAssert:fail[Option "$strName" is not found.]
      }
   }

#----- Private -----

@_loadConfig[]
  $tArgs[^table::create{arg}]
  ^tArgs.append{-show-config}

  $fVersion[^file::exec[$self._tidy._TIDY_PATH;;-show-config]]

  $self._loadedConfig[^_parseConfig[$fResult.text]]

  $self._isConfigLoaded(true)

@_parseConfig[strData]
  $result[^hash::create[]]

  $tMatches[^strData.match[
    ^([a-z\d\-]+)
    [\x20]+
    (String|Boolean|Tag\x20names|DocType|Integer|AutoBool|enum|Encoding)
    [\x20]+
    ([\w\-\*]+)?
  ][gx]]

  ^pfAssert:isTrue($tMatches)[Configuration options is empty.]

  ^tMatches.menu{
    $aData[$tMatches.3]

    ^if((^tMatches.2.lower[] eq "boolean" || ^tMatches.2.lower[] eq "autobool") && $tMatches.3 ne "auto"){
      $aData($tMatches.3 eq "yes")
    }

    $sConfigName[^_parseName[$tMatches.1]]

    $result.[$sConfigName][$aData]
  }

  $result.doctypeMode[]

@_parseName[strName]
  $result[^strName.match[$self._abbrRegex][g]{^match.1.upper[]}]
  $result[^result.match[-([\w])][g]{^match.1.upper[]}]

@_restoreName[strName]
  $result[^strName.match[$self._abbrRegex][gi]{^pfString:changeCase[$match.1;first]}]
  $result[^result.match[([A-Z])][g]{-^match.1.lower[]}]

  $result[^result.match[^^word2000^$][]{word-2000}]